from math import *
from copy import deepcopy


# Turns a color myro.graphics.Picture into a grayscale one
def toGray(pic):
    for pixel in getPixels(pic):
        r,g,b = getRGB(pixel)
        gray = int(.3*r + .59*g + .11*b)
        setRGB(pixel,(gray,gray,gray))

# Turns a grayscale image into a simple 2d grayscale array
def toGrayRay(grayPic):
    ray = []
    for rpx in range(256):
        arow = []
        for cpx in range(192):
            pixel = getPixel(grayPic,rpx,cpx)
            r = getRed(pixel)
            arow.append(getRed(pixel))
        ray.append(arow)
    return ray

# Turns any 2d  array into a 1d one
def to1dRay(ray2d):
    ray = []
    for row in ray2d:
        ray += row
    return ray
         
# calculate the standard deviation of the values in a 1-d array given the
# mean as input
def stanDev(mean,ray):
    return sqrt(sum(map((lambda x: (x-mean)*(x-mean)),ray))/len(ray))

# Looks for edges in a 2d grayscale image {simple-minded alg}
def edgeList2(ray2d,mean,dif):
    edges = []
    rLen = len(ray2d)
    for rpx in range(rLen):
        cLen = len(ray2d[rpx])
        for cpx in range(cLen):
            if inRange(rpx,cpx,2,rLen,cLen):
                if isEdge2(rpx,cpx,ray2d,mean,dif):
                    edges.append([rpx,cpx])
    return edges

# Determine whether given x,y value is within range
def inRange(x,y,dist,xSize,ySize):
    return x-dist >= 0 and y-dist >= 0 and x+dist < xSize and y+dist < ySize

# Simple-minded edge detection
def isEdge2(x,y,ray,mean,dif):
    return (ray[x+1][y] > mean+dif and ray[x+2][y] > mean+dif and ray[x-1][y] < mean-dif and ray[x-2][y] < mean-dif) or (ray[x+1][y] < mean-dif and ray[x+2][y] < mean-dif and ray[x-1][y] > mean+dif and ray[x-2][y] > mean+dif) or(ray[x][y+1] > mean+dif and ray[x][y+2] > mean+dif and ray[x][y-1] < mean-dif and ray[x][y-2] < mean-dif) or(ray[x][y+1] < mean-dif and ray[x][y+2] < mean-dif and ray[x][y-1] > mean+dif and ray[y][y-2] > mean+dif)

# Looks for edges in a 2d grayscale image {simple-minded alg} and returns a myro.graphics.Picture
# with edge pixels black and all others white
def showEdges2(ray2d,mean,dif,myroPic):
    rLen = len(ray2d)
    for rpx in range(rLen):
        cLen = len(ray2d[rpx])
        for cpx in range(cLen):
            if inRange(rpx,cpx,2,rLen,cLen):
                if isEdge2(rpx,cpx,ray2d,mean,dif):
                    pixel = getPixel(myroPic,rpx,cpx)
                    setRGB(pixel,(0,0,0))

# Attempt to improve on simple-minded edge detection
def isEdge(x,y,ray,dif):
    this = ray[x][y]
    higher = this+dif
    lower = this-dif
    return (ray[x+1][y] > higher and ray[x+2][y] > higher and ray[x-1][y] < lower and ray[x-2][y] < lower) or (ray[x+1][y] < lower and ray[x+2][y] < lower and ray[x-1][y] > higher and ray[x-2][y] > higher) or(ray[x][y+1] > higher and ray[x][y+2] > higher and ray[x][y-1] < lower and ray[x][y-2] < lower) or(ray[x][y+1] < lower and ray[x][y+2] < lower and ray[x][y-1] > higher and ray[y][y-2] > higher)

# Looks for edges in a 2d grayscale image and returns a myro.graphics.Picture
# with edge pixels black and all others white
def showEdges(ray2d,dif,myroPic):
    rLen = len(ray2d)
    for rpx in range(rLen):
        cLen = len(ray2d[rpx])
        for cpx in range(cLen):
            if inRange(rpx,cpx,2,rLen,cLen):
                if isEdge(rpx,cpx,ray2d,dif):
                    pixel = getPixel(myroPic,rpx,cpx)
                    setRGB(pixel,(0,0,0))
         
